package LeetCode1;

/**
 * 剑指offer 51 求数组的逆序对
 * 在归并排序中加入一个类似于计数器的东西
 * @author 是阿秋啊
 * @date 2022/03/20 12:15
 **/
public class Num51_ArrNiXu {
    public int reversePairs(int[] nums) {
        return reversePairsHelper(nums, 0, nums.length - 1);
    }

    private int reversePairsHelper(int[] nums, int l, int r) {
        if (l >= r) {
            return 0;
        }
        int mid = l + (r - l) / 2;
        int left = reversePairsHelper(nums, l, mid);
        int right = reversePairsHelper(nums, mid + 1, r);
        if (nums[mid] > nums[mid + 1]) {
            return merge(nums, l, mid, r) + left + right;
        }
        return left + right;
    }

    private int merge(int[] nums, int l, int mid, int r) {
        int[] aux = new int[r - l + 1];
        for (int i = 0; i < aux.length; i++) {
            aux[i] = nums[i + l];
        }
        int ret = 0;
        int i = l;
        int j = mid + 1;
        for (int k = l; k <= r; k++) {
            if (i > mid) {
                nums[k] = aux[j - l];
                j++;
            } else if (j > r) {
                nums[k] = aux[i - l];
                i++;
            } else if (aux[i - l] <= aux[j - l]) {
                nums[k] = aux[i - l];
                i++;
            } else {
                nums[k] = aux[j - l];
                ret += mid - i + 1;
                j++;
            }
        }
        return ret;
    }
}
